package com.xpxrule.service.impl;

import com.xpxrule.AviatorExecuteUtil;
import com.xpxrule.dataobject.bo.AviatorMatchBo;
import com.xpxrule.dataobject.dao.ModelItem;
import com.xpxrule.dataobject.dao.Rule;
import com.xpxrule.dataobject.req.RuleMatchReq;
import com.xpxrule.dataobject.vo.RuleVo;
import com.xpxrule.service.RuleMatchService;
import com.xpxrule.service.RuleScenariosService;
import com.xpxrule.service.RuleService;
import com.xpxrule.util.ModelConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Author xiangpengxiang
 * @Date 2024/12/20 14:36
 * @注释
 */
@Service
public class RuleMatchServiceImpl implements RuleMatchService {
    @Autowired
    private RuleService ruleService;
    @Autowired
    private RuleScenariosService ruleScenariosService;

    /**
     * 匹配规则
     * @param request
     * @return
     */
    @Override
    public List<RuleVo> matchRule(RuleMatchReq request) {
        // 获取规则场景下所有启用规则
        List<Rule> rules = ruleService.selectRuleListByRuleScenarios(request.getRuleScenariosKey());
        // 规则过滤
        rules = AviatorExecuteUtil.filterRuleByTimeRange(rules, request.getOccurrenceTime());
        List<RuleVo> ruleVoList = rules.stream()
                .map(ModelConvertUtil::convertRuleToRuleVo)
                .collect(Collectors.toList());
        // 字段过滤
        // 获取规则场景条件模型
        List<ModelItem> conditionModelItemList = ruleScenariosService.getConditionModelByScenariosKey(request.getRuleScenariosKey());
        Map<String, Object> filterParams = AviatorExecuteUtil.filterAndFillFieldByModelItem(request.getParams(), conditionModelItemList);
        // todo xpx 深度解析filterParams，将多层级map打平
        // 执行匹配逻辑
        Map<Long, AviatorMatchBo> matchedResult = new HashMap<>();
        ruleVoList.forEach(ruleVo -> {
            AviatorMatchBo matchedBo = null;
            try {
                matchedBo = AviatorExecuteUtil.isMatch(ruleVo, filterParams);
            } catch (Exception e) {
                throw new RuntimeException(e);// todo xpx 异常返回
            }
            matchedResult.put(Long.valueOf(ruleVo.getId()), matchedBo);
        });
        Map<String, RuleVo> ruleVoMap = new HashMap<>();
        ruleVoList.forEach(ruleVo -> ruleVoMap.put(String.valueOf(ruleVo.getId()), ruleVo));
        List<RuleVo> resultRuleVoList = new ArrayList<>();
        for (Map.Entry<Long, AviatorMatchBo> entry : matchedResult.entrySet()) {
            String ruleId = String.valueOf(entry.getKey());
            RuleVo ruleVo = ruleVoMap.get(ruleId);
            resultRuleVoList.add(ruleVo);
        }
        return resultRuleVoList;
    }

}
